package com.mars.pay.service;

import com.google.gson.Gson;
import com.mars.pay.common.PaymentStatusEnum;
import com.mars.pay.common.PaymentTypeEnum;
import com.mars.pay.config.WechatPayConfig;
import com.mars.pay.entity.Order;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 微信支付服务
 *
 * @author Mars
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WechatPayService {

    private final WechatPayConfig wechatPayConfig;
    private final NativePayService nativePayService;
    private final RSAAutoCertificateConfig rsaAutoCertificateConfig;
    private final OrderService orderService;
    private final PaymentLogService paymentLogService;
    private final Gson gson;

    /**
     * Native 支付下单
     *
     * @param order 订单信息
     * @return 二维码链接
     */
    public String nativePay(Order order) {
        try {
            // 构建请求参数
            PrepayRequest request = new PrepayRequest();
            
            // 应用 ID
            request.setAppid(wechatPayConfig.getAppId());
            
            // 商户号
            request.setMchid(wechatPayConfig.getMchId());
            
            // 商品描述
            request.setDescription(order.getProductName());
            
            // 商户订单号
            request.setOutTradeNo(order.getOrderNo());
            
            // 回调地址
            request.setNotifyUrl(wechatPayConfig.getNotifyUrl());
            
            // 订单金额（单位：分）
            Amount amount = new Amount();
            amount.setTotal(order.getAmount().multiply(new BigDecimal("100")).intValue());
            amount.setCurrency("CNY");
            request.setAmount(amount);

            // 调用下单接口
            PrepayResponse response = nativePayService.prepay(request);
            String codeUrl = response.getCodeUrl();
            
            // 更新订单状态为支付中
            orderService.updateOrderStatus(order.getOrderNo(), PaymentStatusEnum.PAYING.getCode(), 
                    null, PaymentTypeEnum.WECHAT.getCode());
            
            // 记录日志
            paymentLogService.recordLog(order.getOrderNo(), null, PaymentTypeEnum.WECHAT.getCode(),
                    "CREATE", gson.toJson(request), gson.toJson(response), 1, "微信Native支付下单成功");
            
            log.info("微信支付下单成功：订单号={}, 二维码={}", order.getOrderNo(), codeUrl);
            
            return codeUrl;
        } catch (Exception e) {
            log.error("微信支付下单失败：订单号={}", order.getOrderNo(), e);
            
            // 记录错误日志
            paymentLogService.recordLog(order.getOrderNo(), null, PaymentTypeEnum.WECHAT.getCode(),
                    "CREATE", null, e.getMessage(), 0, "微信Native支付下单失败");
            
            throw new RuntimeException("微信支付下单失败：" + e.getMessage(), e);
        }
    }

    /**
     * 处理微信支付回调通知
     *
     * @param requestParam 回调参数
     * @return 处理结果
     */
    public boolean handleNotify(RequestParam requestParam) {
        try {
            // 验签并解析通知数据
            NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            
            String outTradeNo = transaction.getOutTradeNo();
            String transactionId = transaction.getTransactionId();
            Transaction.TradeStateEnum tradeState = transaction.getTradeState();
            
            log.info("收到微信支付回调：订单号={}, 交易号={}, 状态={}", 
                    outTradeNo, transactionId, tradeState);
            
            // 查询订单
            Order order = orderService.getByOrderNo(outTradeNo);
            if (order == null) {
                log.warn("订单不存在：{}", outTradeNo);
                return false;
            }
            
            // 判断订单状态
            if (PaymentStatusEnum.SUCCESS.getCode().equals(order.getStatus())) {
                log.info("订单已支付，无需重复处理：{}", outTradeNo);
                return true;
            }
            
            // 根据支付状态更新订单
            if (Transaction.TradeStateEnum.SUCCESS.equals(tradeState)) {
                orderService.updateOrderStatus(outTradeNo, PaymentStatusEnum.SUCCESS.getCode(), 
                        transactionId, PaymentTypeEnum.WECHAT.getCode());
                
                // 记录日志
                paymentLogService.recordLog(outTradeNo, transactionId, PaymentTypeEnum.WECHAT.getCode(),
                        "NOTIFY", gson.toJson(requestParam), gson.toJson(transaction), 1, "支付成功");
                
                log.info("订单支付成功：{}", outTradeNo);
                return true;
            } else {
                // 支付失败
                orderService.updateOrderStatus(outTradeNo, PaymentStatusEnum.FAILED.getCode(), 
                        transactionId, PaymentTypeEnum.WECHAT.getCode());
                
                // 记录日志
                paymentLogService.recordLog(outTradeNo, transactionId, PaymentTypeEnum.WECHAT.getCode(),
                        "NOTIFY", gson.toJson(requestParam), gson.toJson(transaction), 0, 
                        "支付失败：" + tradeState);
                
                log.warn("订单支付失败：订单号={}, 状态={}", outTradeNo, tradeState);
                return false;
            }
        } catch (Exception e) {
            log.error("处理微信支付回调失败", e);
            
            // 记录错误日志
            paymentLogService.recordLog(null, null, PaymentTypeEnum.WECHAT.getCode(),
                    "NOTIFY", gson.toJson(requestParam), e.getMessage(), 0, "回调处理异常");
            
            return false;
        }
    }

    /**
     * 查询支付状态
     *
     * @param orderNo 订单号
     * @return 订单状态
     */
    public Transaction queryOrder(String orderNo) {
        try {
            QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
            request.setMchid(wechatPayConfig.getMchId());
            request.setOutTradeNo(orderNo);
            
            Transaction transaction = nativePayService.queryOrderByOutTradeNo(request);
            
            log.info("查询微信支付状态：订单号={}, 状态={}", orderNo, transaction.getTradeState());
            
            // 记录日志
            paymentLogService.recordLog(orderNo, transaction.getTransactionId(), 
                    PaymentTypeEnum.WECHAT.getCode(), "QUERY", gson.toJson(request), 
                    gson.toJson(transaction), 1, "查询成功");
            
            return transaction;
        } catch (Exception e) {
            log.error("查询微信支付状态失败：订单号={}", orderNo, e);
            
            // 记录日志
            paymentLogService.recordLog(orderNo, null, PaymentTypeEnum.WECHAT.getCode(),
                    "QUERY", null, e.getMessage(), 0, "查询失败");
            
            throw new RuntimeException("查询支付状态失败：" + e.getMessage(), e);
        }
    }
}

